#include "helper.h"
#include "WidgetWrapper.h"
#include "WindowWrapper.h"
#include "WindowDelegateWrapper.h"

namespace BerkeliumDotNet
{
	Window::Window()
	{
		window = Berkelium::Window::create();
		windowDelegateWrapper = new WindowDelegateWrapper(this);
	}

	Window::Window(Berkelium::Context* otherContext)
	{
		window = Berkelium::Window::create(*otherContext);
		windowDelegateWrapper = new WindowDelegateWrapper(this);
	}

	Window::Window(Berkelium::Window* window)
	{
		this->window = window;
		windowDelegateWrapper = new WindowDelegateWrapper(this);
	}

	Window::~Window()
	{
		window->setDelegate(0);
		delete windowDelegateWrapper;
		delete windowDelegate;
		delete window;
		window = 0;
	}

	Widget^ Window::Widget::get()
	{
		Berkelium::Widget* widget = window->getWidget();
		if (widget != nullptr)
			return gcnew BerkeliumDotNet::Widget(widget);
		else
			return nullptr;
	}

	Context^ Window::Context::get()
	{
		Berkelium::Context* context = window->getContext();
		if (context != nullptr)
			return gcnew BerkeliumDotNet::Context(context);
		else
			return nullptr;
	}

	void Window::AppendWidget(BerkeliumDotNet::Widget^ widget)
	{
		window->appendWidget(widget->widget);
	}

	void Window::RemoveWidget(BerkeliumDotNet::Widget^ widget)
	{
		window->removeWidget(widget->widget);
	}

	Window^ Window::Create()
	{
		return gcnew Window();
	}

	Window^ Window::Create(BerkeliumDotNet::Context^ otherContext)
	{
		return gcnew Window(otherContext->context);
	}

	void Window::Focus()
	{
		window->focus();
	}

	void Window::Unfocus()
	{
		window->unfocus();
	}

	void Window::MouseMoved(int xPos, int yPos)
	{
		window->mouseMoved(xPos, yPos);
	}
	
	void Window::MouseButton(unsigned int buttonId, bool down)
	{
		window->mouseButton(buttonId, down);
	}
	
	void Window::MouseWheel(int xScroll, int yScroll)
	{
		window->mouseWheel(xScroll, yScroll);
	}

	void Window::TextEvent(char event, size_t eventLength)
	{
		window->textEvent((const wchar_t*)event, eventLength);
	}

	void Window::KeyEvent(bool pressed, int modifiers, int vkCode, int scancode)
	{
		window->keyEvent(pressed, modifiers, vkCode, scancode);
	}

	void Window::ExecuteJavaScript(String^ javaScript)
	{
		std::wstring javaScriptString = MarshalStringW(javaScript);
		window->executeJavascript(javaScriptString.c_str(), javaScriptString.length());
	}

	bool Window::NavigateTo(String^ url)
	{
		std::string urlString = MarshalString(url);
		return window->navigateTo(urlString.c_str(), urlString.length());
	}

	void Window::Refresh()
	{
		window->refresh();
	}

	void Window::Resize(int width, int height)
	{
		window->resize(width, height);
	}

	void Window::SetDelegate(WindowDelegate^ windowDelegate)
	{
		this->windowDelegate = windowDelegate;
		if (windowDelegate != nullptr)
			window->setDelegate(windowDelegateWrapper);
		else
			window->setDelegate(0);
	}

	void Window::SetTransparent(bool isTransparent)
	{
		window->setTransparent(isTransparent);
	}

	void Window::Cut()
	{
		window->cut();
	}

	void Window::Copy()
	{
		window->copy();
	}
	
	void Window::Paste()
	{
		window->paste();
	}
	
	void Window::Undo()
	{
		window->undo();
	}
	
	void Window::Redo()
	{
		window->redo();
	}
	
	void Window::Delete()
	{
		window->del();
	}
	
	void Window::SelectAll()
	{
		window->selectAll();
	}
}
